﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Reflection;
using System.Data;

namespace Efficient.Excel
{
    internal class PropertyValueSetter : IPropertyValueSetter 
    {
        private readonly static IDictionary<Type, SimpleType> typeMap = new Dictionary<Type, SimpleType>();
        private readonly IDataReaderValueGetter getter;
        private readonly PropertyInfo property;
        private readonly string readerFieldName;
        static PropertyValueSetter()
        {
            typeMap.Add(typeof(Boolean), SimpleType.Boolean);
            typeMap.Add(typeof(Byte), SimpleType.Byte);
            typeMap.Add(typeof(Char), SimpleType.Char);
            typeMap.Add(typeof(DateTime), SimpleType.DateTime);
            typeMap.Add(typeof(Decimal), SimpleType.Decimal);
            typeMap.Add(typeof(Double), SimpleType.Double);
            typeMap.Add(typeof(Single), SimpleType.Float);
            typeMap.Add(typeof(Int16), SimpleType.Int16);
            typeMap.Add(typeof(Int32), SimpleType.Int32);
            typeMap.Add(typeof(Int64), SimpleType.Int64);
            typeMap.Add(typeof(String), SimpleType.String);
            typeMap.Add(typeof(Object), SimpleType.Object);
        }



        public PropertyValueSetter(PropertyInfo property, string valMap, string readerFieldName)
            : this(property, null, valMap, readerFieldName)
        { 
            
        }

        public PropertyValueSetter(PropertyInfo property, IDataReaderValueGetter getter, string valMap, string readerFieldName)
        {
            this.property = property;
            this.readerFieldName = readerFieldName;
            if (getter == null)
            {
                if (typeMap.ContainsKey(this.property.PropertyType))
                {
                    this.getter = ReaderValueGetterBuilder.Build(typeMap[this.property.PropertyType], valMap);
                }
                return;
            }
            this.getter = getter;
        }

        public PropertyValueSetter(PropertyInfo property)
            : this(property, null, string.Empty, string.Empty)
        {
        }


        public void Execute(object entity, IDataReader reader)
        {
            if (this.property.CanWrite)
            {
                if (this.getter == null)
                {
                    throw new NullReferenceException("DataReader 字段获取器为空，这可能是因为实体字段:" + this.property.Name + "的类型:" + this.property.PropertyType.FullName + "没有对应的获取器");
                }
                string name = string.IsNullOrEmpty(readerFieldName) ? this.property.Name : readerFieldName;
                object val = getter.GetValue(reader, name);
                this.property.SetValue(entity, val, null);

            }
        }


        
    }
}
